/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Client.java
 *
 * Created on Apr 29, 2011, 8:30:49 PM
 */
package ClientSide;

import com.sun.corba.se.impl.orbutil.concurrent.Sync;
import model.*;
import java.io.*;
import java.util.logging.*;
import java.util.*;
import javax.swing.JFileChooser;
import javax.swing.table.DefaultTableModel;
import helper.*;
import controller.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

/**
 *
 * @author ImNotPro
 */
public class Client extends javax.swing.JFrame {

    private boolean isSync = false;
    private boolean isLogin = false;
    private LastRevisionCheacker revCheck;
    private LastModifiedChecker checker;
    public static ArrayList<WorkingDirectory> WD = new ArrayList<WorkingDirectory>();

    /** Creates new form Client */
    public Client() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        synchronizeButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        model = new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "Folder", "Path"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        };
        WorkingTable = new javax.swing.JTable(model);
        AddButton = new javax.swing.JButton();
        Username = new javax.swing.JTextField();
        Password = new javax.swing.JPasswordField();
        LoginButton = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        RevertText = new javax.swing.JTextField();
        RevertButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        synchronizeButton.setText("Start");
        synchronizeButton.setEnabled(false);
        synchronizeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                synchronizeButtonActionPerformed(evt);
            }
        });

        WorkingTable.setModel(model);
        WorkingTable.setEnabled(false);
        jScrollPane1.setViewportView(WorkingTable);

        AddButton.setText("Add");
        AddButton.setEnabled(false);
        AddButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AddButtonActionPerformed(evt);
            }
        });

        LoginButton.setText("Login");
        LoginButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                LoginButtonActionPerformed(evt);
            }
        });

        jLabel1.setText("Revert Version");

        RevertText.setEnabled(false);

        RevertButton.setText("Change");
        RevertButton.setEnabled(false);
        RevertButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                RevertButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(synchronizeButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 267, Short.MAX_VALUE)
                        .addComponent(AddButton))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                .addComponent(jLabel1)
                                .addGap(18, 18, 18)
                                .addComponent(RevertText, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addComponent(RevertButton))
                            .addComponent(Password, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
                            .addComponent(Username, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE))
                        .addGap(18, 18, 18)
                        .addComponent(LoginButton)
                        .addGap(12, 12, 12)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Username, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(LoginButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(Password, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(RevertText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(RevertButton))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(synchronizeButton)
                    .addComponent(AddButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(11, Short.MAX_VALUE))
        );

        synchronizeButton.getAccessibleContext().setAccessibleName("synchronizeButton");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void synchronizeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_synchronizeButtonActionPerformed
        // TODO add your handling code here:
        isSync = !isSync;
        if (isSync) {
            
            this.checker = new LastModifiedChecker();
            this.checker.setWD(WD);
            this.checker.setUsername(Username.getText());
            this.checker.start();
            
            this.revCheck = new LastRevisionCheacker();
            this.revCheck.setClientWD(WD);
            this.revCheck.setUsername(Username.getText());
            this.revCheck.start();

            AddButton.setEnabled(false);
            synchronizeButton.setText("Stop");
        } else {
            this.revCheck.stop();
            this.checker.stop();
            AddButton.setEnabled(true);
            synchronizeButton.setText("Start");
        }
    }//GEN-LAST:event_synchronizeButtonActionPerformed

    private void AddButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddButtonActionPerformed
        // TODO add your handling code here:

        JFileChooser chooser = new JFileChooser();
        chooser.setCurrentDirectory(new java.io.File("."));
        chooser.setDialogTitle("Directory to Syncronize");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.setAcceptAllFileFilterUsed(false);
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {

            Object[] obj = new Object[]{chooser.getSelectedFile().getName(), chooser.getCurrentDirectory()};
            model.insertRow(WD.size(), obj);
            WorkingDirectory temp = new WorkingDirectory();
            temp.setDir(chooser.getSelectedFile().getName());
            temp.setPath(chooser.getCurrentDirectory().toString());
            WD.add(temp);
            //deleteDirectory(chooser.getSelectedFile());
        } else {
            System.out.println("No Selection ");
        }
    }//GEN-LAST:event_AddButtonActionPerformed

    private void LoginButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_LoginButtonActionPerformed
        if (!isLogin) {
            try {
                // TODO add your handling code here:
                boolean acep = Connect.login(Username.getText(), MD5(Password.getText()));
                if (acep) {
                    ChangeButton(acep);
                    LoginButton.setText("Log Out");
                } else {
                    System.out.println("Username and password don't match");
                }
            } catch (Exception ex) {
                Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            ChangeButton(false);
            LoginButton.setText("Login");
        }
    }//GEN-LAST:event_LoginButtonActionPerformed

    private void RevertButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RevertButtonActionPerformed
        // TODO add your handling code here:
        int version = Integer.parseInt(RevertText.getText());
        if (version > 0) {
            try {
                ArrayList<WorkingDirectory> newWD = Connect.getStructure(Username.getText(), version);
                ControllerWD.WDclientWriterRevert(WD, newWD);
            } catch (Exception ex) {
                Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }//GEN-LAST:event_RevertButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Client().setVisible(true);
            }
        });
    }

    private static String convertToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            int halfbyte = (data[i] >>> 4) & 0x0F;
            int two_halfs = 0;
            do {
                if ((0 <= halfbyte) && (halfbyte <= 9))
                    buf.append((char) ('0' + halfbyte));
                else
                    buf.append((char) ('a' + (halfbyte - 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        }
        return buf.toString();
    }

    public static String MD5(String text)
    throws NoSuchAlgorithmException, UnsupportedEncodingException  {
    MessageDigest md;
    md = MessageDigest.getInstance("MD5");
    byte[] sha1hash = new byte[40];
    md.update(text.getBytes("iso-8859-1"), 0, text.length());
    sha1hash = md.digest();
    return convertToHex(sha1hash);
    }

    private void ChangeButton(Boolean value) {
        AddButton.setEnabled(value);
        synchronizeButton.setEnabled(value);
        WorkingTable.setEnabled(value);
        Password.setEditable(!value);
        Username.setEnabled(!value);
        RevertButton.setEnabled(value);
        RevertText.setEnabled(value);
        isLogin = value;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton AddButton;
    private javax.swing.JButton LoginButton;
    private javax.swing.JPasswordField Password;
    private javax.swing.JButton RevertButton;
    private javax.swing.JTextField RevertText;
    private javax.swing.JTextField Username;
    private DefaultTableModel model;
    private javax.swing.JTable WorkingTable;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton synchronizeButton;
    // End of variables declaration//GEN-END:variables
}
